#!/usr/bin/env ruby

require 'rubygems'
gem 'OptionParser'
gem 'sequel'
gem 'sequel_pg'
gem 'json'

require 'commandline/optionparser'
require 'sequel'
require 'json'
require 'json/pure'
require 'pp'

require 'database'
require 'metalize'

include CommandLine

optParser = OptionParser.new do |opt|

	opt <<  Option.new(
		:names			=>	["--dbuser", "-U"],
		:arg_arity		=>	[1, 1],
		:opt_description	=>	"Set the database user",
		:opt_not_found		=> 	OptionParser::OPT_NOT_FOUND_BUT_REQUIRED,
		:opt_found 		=> 	OptionParser::GET_ARGS
		)
	opt << Option.new(
		:names			=>	["--dbpasswd", "-W"],
		:arg_arity		=>	[1, 1],
		:opt_description	=>	"Set the database password",
		:opt_not_found		=> 	OptionParser::OPT_NOT_FOUND_BUT_REQUIRED,
		:opt_found 		=> 	OptionParser::GET_ARGS
		)
	opt << Option.new(
		:names			=>	["--dbhost", "-H"],
		:arg_arity		=>	[1, 1],
		:opt_description	=>	"Set the database host",
		:opt_not_found		=> 	OptionParser::OPT_NOT_FOUND_BUT_REQUIRED,
		:opt_found 		=> 	OptionParser::GET_ARGS
		)
	opt <<  Option.new(
		:names			=>	["--dbname", "-D"],
		:arg_arity		=>	[1, 1],
		:opt_description	=>	"Set the database name",
		:opt_not_found		=> 	OptionParser::OPT_NOT_FOUND_BUT_REQUIRED,
		:opt_found 		=> 	OptionParser::GET_ARGS
		)
	opt << Option.new(
		:names			=>	["--target", "-t", "-T"],
		:arg_arity		=>	[1, -1],
		:opt_description	=>	"Choose the table to convert from",
		:opt_not_found		=> 	OptionParser::OPT_NOT_FOUND_BUT_REQUIRED,
		:opt_found 		=> 	OptionParser::GET_ARGS
		)
	opt << Option.new(
		:names			=>	["--meta", "-mt", "-M"],
		:arg_arity		=>	[1, 1],
		:opt_description	=>	"Choose the meta-table to convert to",
		:opt_not_found		=> 	OptionParser::OPT_NOT_FOUND_BUT_REQUIRED,
		:opt_found 		=> 	OptionParser::GET_ARGS
		)
	opt << Option.new(
		:names			=>	["--excludecolumns", "-X"],
		:arg_arity		=>	[1, -1],
		:opt_description	=>	"Exclude columns of the convertion",
		:opt_found 		=> 	OptionParser::GET_ARGS
		)
	opt << Option.new(
		:names			=>	["--metacolumn", "-mc", "-C"],
		:arg_arity		=>	[1, 1],
		:opt_description	=>	"Choose the meta-table's column to use",
		:opt_not_found		=> 	OptionParser::OPT_NOT_FOUND_BUT_REQUIRED,
		:opt_found 		=> 	OptionParser::GET_ARGS
		)
	opt << Option.new(
		:names			=>	["--insertifexists", "-a"],
		:arg_arity		=>	[0, 0],
		:opt_description	=>	"If the meta table exists insert into it"
		)
	opt << Option.new(
		:names			=>	["--dropifexists", "-b"],
		:arg_arity		=>	[0, 0],
		:opt_description	=>	"If the meta table exists drop it"
		)
	opt << Option.new(
		:names			=>	["--abortifexists", "-z"],
		:arg_arity		=>	[0, 0],
		:opt_description	=>	"If the meta table exists abort"
		)

end

begin
	cmdOptions = optParser.parse(ARGV)
rescue OptionParser::MissingRequiredOptionError => msg
	$stderr.puts msg
	$stderr.puts

	$stderr.puts "Usage: table2meta [options]"
	$stderr.puts optParser.to_s
	
	exit
end

dbConn = Sequel.connect("postgres://#{cmdOptions['--dbuser']}:#{cmdOptions['--dbpasswd']}@#{cmdOptions['--dbhost']}/#{cmdOptions['--dbname']}")

metaTableOption = :none
if (cmdOptions['--dropifexists'])
	metaTableOption = :dropit
elsif(cmdOptions['--insertifexists'])
	metaTableOption = :insertinto
elsif(cmdOptions['--abortifexists'])
	metaTableOption = :abort
end

dbMetalize = DBMetalize.new(dbConn, cmdOptions['--meta']);

if (dbConn.table_exists? cmdOptions['--meta'])
	ans = "none"
	if (metaTableOption==:none)
		puts "The table \"#{cmdOptions['--meta']}\" already exists. insert into this table (i) ? drop this table (d) ? abort (a) ?"
		ans = $stdin.gets.chomp.downcase	
	end
	
	if (metaTableOption==:dropit || ans =~ /^d/)
		metaTableOption = :dropit
		dbMetalize.dropMetaTable()
	elsif (metaTableOption == :insertinto || ans =~ /^i/)
		metaTableOption = :insertinto
		#do nothing
	else
		puts "aborted."
		exit
	end
end

if (metaTableOption == :dropit)
	dbMetalize.createMetaTable()
end 

if (!(dbConn.table_exists?cmdOptions['--target']))
	$stderr.puts "The target table \"#{cmdOptions['--target']}\" does not exist."
	exit
end

dbMetalize.convertTable(cmdOptions['--target'], cmdOptions['--excludecolumns'] ? cmdOptions['--excludecolumns'] : [])
